package sw6.admin;

import sw6.admin.database.DatabaseHelper;
import sw6.lib.internal.PrivateDefinitions;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.net.Uri;

public class SettingsProvider extends ContentProvider {
	private static final UriMatcher URL_MATCHER;
	private static final int MATCH_OBJECT			= 1;
	private static final int MATCH_BOOLEAN			= 2;
	private static final int MATCH_INTEGER			= 3;
	private static final int MATCH_DOUBLE			= 4;
	private static final int MATCH_STRING			= 5;
	private static final int MATCH_ENUM				= 6;
	private static final int MATCH_ENUM_ELEMENT		= 7;
	private static final int MATCH_INSERT_INTEGER	= 8;
	private static final int MATCH_INSERT_DOUBLE	= 9;
	private static final int MATCH_INSERT_STRING	= 10;
	
	private DatabaseHelper dbHelper;
	
	static {
		// content://sw6.admin.settingsprovider/TYPE/APP_NAME/VAR_NAME/
		URL_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
		URL_MATCHER.addURI(PrivateDefinitions.PROVIDER_CLASS, PrivateDefinitions.OBJECT			+ "/*/*/*", MATCH_OBJECT);
		URL_MATCHER.addURI(PrivateDefinitions.PROVIDER_CLASS, PrivateDefinitions.BOOLEAN		+ "/*/*", 	MATCH_BOOLEAN);
		URL_MATCHER.addURI(PrivateDefinitions.PROVIDER_CLASS, PrivateDefinitions.INTEGER		+ "/*/*", 	MATCH_INTEGER);
		URL_MATCHER.addURI(PrivateDefinitions.PROVIDER_CLASS, PrivateDefinitions.DOUBLE			+ "/*/*", 	MATCH_DOUBLE);
		URL_MATCHER.addURI(PrivateDefinitions.PROVIDER_CLASS, PrivateDefinitions.STRING			+ "/*/*",	MATCH_STRING);
		URL_MATCHER.addURI(PrivateDefinitions.PROVIDER_CLASS, PrivateDefinitions.ENUM			+ "/*/*",	MATCH_ENUM);
		URL_MATCHER.addURI(PrivateDefinitions.PROVIDER_CLASS, PrivateDefinitions.ENUM_ELEMENT	+ "/*/*",	MATCH_ENUM_ELEMENT);
		
		URL_MATCHER.addURI(PrivateDefinitions.PROVIDER_CLASS, PrivateDefinitions.INTEGER		+ "/*/*/*/*", 	MATCH_INSERT_INTEGER);
		URL_MATCHER.addURI(PrivateDefinitions.PROVIDER_CLASS, PrivateDefinitions.DOUBLE			+ "/*/*/*/*", 	MATCH_INSERT_DOUBLE);
		URL_MATCHER.addURI(PrivateDefinitions.PROVIDER_CLASS, PrivateDefinitions.STRING			+ "/*/*/*/*",	MATCH_INSERT_STRING);
	}
	
	@Override
	public boolean onCreate() {
		dbHelper = new DatabaseHelper(getContext());
		return true;
	}

	@Override
	public String getType(Uri uri) {
		// I don't think we need to provide this "service" because we are makring our own
		// implementation (sw6.lib.Settings) to communicate with this content provider
		return null;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		Cursor resultCursor = null;
		int match = URL_MATCHER.match(uri);

		if (match != -1) {
			String appName	= uri.getPathSegments().get(1);
			String varName	= uri.getPathSegments().get(2);
			
			switch (match) {
				case MATCH_ENUM:
					resultCursor = dbHelper.getEnum(appName, varName);
					break;
				case MATCH_OBJECT:
					String varCanonicalClassName = uri.getPathSegments().get(3);
					resultCursor = dbHelper.getObject(appName, varName, varCanonicalClassName);
					break;
				case MATCH_BOOLEAN:
					resultCursor = dbHelper.getBoolean(appName, varName);
					break;
				case MATCH_INTEGER:
					resultCursor = dbHelper.getInteger(appName, varName);
					break;
				case MATCH_DOUBLE:
					resultCursor = dbHelper.getDouble(appName, varName);
					break;
				case MATCH_STRING:
					resultCursor = dbHelper.getString(appName, varName);
					break;
				default:
					return null;
			}
			resultCursor.setNotificationUri(getContext().getContentResolver(), uri);
		}
		return resultCursor;
	}
	
	@Override
	public Uri insert(Uri uri, ContentValues values) {
		int match = URL_MATCHER.match(uri);

		if (match != -1) {
			String appName	= uri.getPathSegments().get(1);
			String varName	= uri.getPathSegments().get(2);
			int minInt = 0;
			int maxInt = 0;
			double minDouble = 0.0;
			double maxDouble = 0.0;
			switch (match) {
				case MATCH_ENUM:
					dbHelper.insertEnum(appName, varName, values.getAsInteger(PrivateDefinitions.VAR_VALUE));
					break;
				case MATCH_ENUM_ELEMENT:
					dbHelper.insertEnumElement(appName, varName, values.getAsInteger(PrivateDefinitions.VAR_VALUE));
					break;
				case MATCH_OBJECT:
					String varCanonicalClassName = uri.getPathSegments().get(3);
					dbHelper.insertObject(appName, varName, varCanonicalClassName, values.getAsByteArray(PrivateDefinitions.VAR_VALUE));
					break;
				case MATCH_BOOLEAN:
					dbHelper.insertBoolean(appName, varName, values.getAsBoolean(PrivateDefinitions.VAR_VALUE));
					break;
				case MATCH_INSERT_INTEGER:
					minInt = Integer.parseInt(uri.getPathSegments().get(3));
					maxInt = Integer.parseInt(uri.getPathSegments().get(4));
					dbHelper.insertInteger(appName, varName, values.getAsInteger(PrivateDefinitions.VAR_VALUE), minInt, maxInt);
					break;
				case MATCH_INSERT_DOUBLE:
					minDouble = Double.parseDouble(uri.getPathSegments().get(3));
					maxDouble = Double.parseDouble(uri.getPathSegments().get(4));
					dbHelper.insertDouble(appName, varName, values.getAsDouble(PrivateDefinitions.VAR_VALUE), minDouble, maxDouble);
					break;
				case MATCH_INSERT_STRING:
					minInt = Integer.parseInt(uri.getPathSegments().get(3));
					maxInt = Integer.parseInt(uri.getPathSegments().get(4));
					dbHelper.insertString(appName, varName, values.getAsString(PrivateDefinitions.VAR_VALUE), minInt, maxInt);
					break;
				default:
					return null;
			}
			getContext().getContentResolver().notifyChange(uri, null);
			return uri;
		}
		return null;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		int returnValue = 0;
		int match = URL_MATCHER.match(uri);

		if (match != -1) {
			String appName	= uri.getPathSegments().get(1);
			String varName	= uri.getPathSegments().get(2);
			switch (match) {
				case MATCH_ENUM:
					dbHelper.updateEnum(appName, varName, values.getAsInteger(PrivateDefinitions.VAR_VALUE));
					returnValue = 1;
					break;
				case MATCH_OBJECT:
					String varCanonicalClassName = uri.getPathSegments().get(3);
					dbHelper.updateObject(appName, varName, varCanonicalClassName, values.getAsByteArray(PrivateDefinitions.VAR_VALUE));
					returnValue = 1;
					break;
				case MATCH_BOOLEAN:
					dbHelper.updateBoolean(appName, varName, values.getAsBoolean(PrivateDefinitions.VAR_VALUE));
					returnValue = 1;
					break;
				case MATCH_INTEGER:
					dbHelper.updateInteger(appName, varName, values.getAsInteger(PrivateDefinitions.VAR_VALUE));
					returnValue = 1;
					break;
				case MATCH_DOUBLE:
					dbHelper.updateDouble(appName, varName, values.getAsDouble(PrivateDefinitions.VAR_VALUE));
					returnValue = 1;
					break;
				case MATCH_STRING:
					dbHelper.updateString(appName, varName, values.getAsString(PrivateDefinitions.VAR_VALUE));
					returnValue = 1;
					break;
				default:
					return 0;
			}
			getContext().getContentResolver().notifyChange(uri, null);
		}
		return returnValue;
	}
	
	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		return 0;
	}

}
